﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.MapEvents.MapEventManager
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using System;
using System.Collections.Generic;
using System.Linq;
using TaleWorlds.CampaignSystem.Encounters;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.MapEvents
{
  public class MapEventManager
  {
    [SaveableField(1)]
    private MBList<MapEvent> _mapEvents;

    internal static void AutoGeneratedStaticCollectObjectsMapEventManager(
      object o,
      List<object> collectedObjects)
    {
      ((MapEventManager) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
    }

    protected virtual void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
    {
      collectedObjects.Add((object) this._mapEvents);
    }

    internal static object AutoGeneratedGetMemberValue_mapEvents(object o)
    {
      return (object) ((MapEventManager) o)._mapEvents;
    }

    public MBReadOnlyList<MapEvent> MapEvents => (MBReadOnlyList<MapEvent>) this._mapEvents;

    internal MapEventManager() => this._mapEvents = new MBList<MapEvent>();

    internal void OnAfterLoad()
    {
      foreach (MapEvent mapEvent in (List<MapEvent>) this._mapEvents)
        mapEvent.OnAfterLoad();
    }

    public void OnMapEventCreated(MapEvent mapEvent) => this._mapEvents.Add(mapEvent);

    internal void Tick()
    {
      for (int index = this._mapEvents.Count - 1; index >= 0; --index)
      {
        if (this._mapEvents[index].IsFinished)
          this._mapEvents.RemoveAt(index);
        else if (this._mapEvents[index].IsRaid || this._mapEvents[index] != MobileParty.MainParty.MapEvent)
          this._mapEvents[index].Update();
      }
    }

    public MapEvent GetMapEvent(int attackerPartyIndex)
    {
      return this._mapEvents.FirstOrDefault<MapEvent>((Func<MapEvent, bool>) (mapEvent => mapEvent.AttackerSide.LeaderParty.Index == attackerPartyIndex));
    }

    public List<MapEvent> GetMapEventsBetweenFactions(IFaction faction1, IFaction faction2)
    {
      List<MapEvent> eventsBetweenFactions = new List<MapEvent>();
      foreach (MapEvent mapEvent in (List<MapEvent>) this._mapEvents)
      {
        MBReadOnlyList<MapEventParty> source1 = mapEvent.PartiesOnSide(BattleSideEnum.Defender);
        MBReadOnlyList<MapEventParty> source2 = mapEvent.PartiesOnSide(BattleSideEnum.Attacker);
        if (source1.Any<MapEventParty>((Func<MapEventParty, bool>) (mapEventParty => mapEventParty.Party.MapFaction == faction1)) && source2.Any<MapEventParty>((Func<MapEventParty, bool>) (mapEventParty => mapEventParty.Party.MapFaction == faction2)) || source1.Any<MapEventParty>((Func<MapEventParty, bool>) (mapEventParty => mapEventParty.Party.MapFaction == faction2)) && source2.Any<MapEventParty>((Func<MapEventParty, bool>) (mapEventParty => mapEventParty.Party.MapFaction == faction1)))
          eventsBetweenFactions.Add(mapEvent);
      }
      return eventsBetweenFactions;
    }

    public void FinalizePlayerMapEvent(MapEvent mapEvent = null)
    {
      if (MobileParty.MainParty.MapEvent == null)
        throw new MBNotFoundException("Trying to finalize a non-existing map event.");
      PartyBase.MainParty.MapEvent.FinalizeEvent();
      PlayerEncounter.Finish();
    }

    public MapEvent StartSiegeMapEvent(PartyBase attackerParty, PartyBase defenderParty)
    {
      MapEvent mapEvent = new MapEvent();
      mapEvent.Initialize(attackerParty, defenderParty, mapEventType: MapEvent.BattleTypes.Siege);
      this.OnMapEventCreated(mapEvent);
      return mapEvent;
    }

    public MapEvent StartSallyOutMapEvent(PartyBase attackerParty, PartyBase defenderParty)
    {
      MapEvent mapEvent = new MapEvent();
      mapEvent.Initialize(attackerParty, defenderParty, mapEventType: MapEvent.BattleTypes.SallyOut);
      this.OnMapEventCreated(mapEvent);
      return mapEvent;
    }

    public MapEvent StartSiegeOutsideMapEvent(PartyBase attackerParty, PartyBase defenderParty)
    {
      MapEvent mapEvent = new MapEvent();
      mapEvent.Initialize(attackerParty, defenderParty, mapEventType: MapEvent.BattleTypes.SiegeOutside);
      this.OnMapEventCreated(mapEvent);
      return mapEvent;
    }
  }
}
